package com.jxin.mall.gateway.config;

import com.jxin.mall.core.util.EnvironmentUtil;
import com.jxin.mall.gateway.properties.RoutesProperties;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.EnvironmentAware;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.core.env.Environment;
import org.springframework.lang.Nullable;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.SwaggerResourcesProvider;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Swagger 配置文件
 * @author  蔡佳新
 * @version 1.0
 * @since   jdk 1.8
 */
@Configuration
@Primary
@Slf4j
public class SwaggerRouterConfiguration implements SwaggerResourcesProvider, EnvironmentAware {
    /**path的旧后缀*/
    private static final String OLD_SUFFIX = "**";
    /**path的新后缀*/
    private static final String NEW_SUFFIX = "/v2/api-docs";
    /**版本号*/
    private static final String VERSION = "2.0";
    /**环境变量对象*/
    private ConfigurableEnvironment environment;

    @Override
    public List<SwaggerResource> get() {
        final Map<String, RoutesProperties.RouteProperties> routes = getRoutes();
        if(routes == null){
            return null;
        }
        final List<SwaggerResource> resources = new ArrayList<>(routes.size());
        routes.forEach((k, v) -> resources.add(swaggerResource(v.getServiceId(),
                                              v.getPath().replace(OLD_SUFFIX, NEW_SUFFIX)))
        );
        return resources;
    }

    /**
     * 从环境变量获取路由列表
     * @return 路由列表
     * @author 蔡佳新
     */
    private Map<String, RoutesProperties.RouteProperties> getRoutes() {
        final Map<String, RoutesProperties.RouteProperties> result;
        try {
            result = EnvironmentUtil.resolveSetting(RoutesProperties.class, "zuul", getEnvironment()).getRoutes();
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            return null;
        }
        return result;
    }


    /**
     *  封装 {@link SwaggerResource}实例
     * @param  name     服务名
     * @param  location 位置
     * @return Swagger数据源
     * @author 蔡佳新
     */
    private SwaggerResource swaggerResource(String name,
                                            String location) {
        SwaggerResource swaggerResource = new SwaggerResource();
        swaggerResource.setName(name);
        swaggerResource.setLocation(location);
        swaggerResource.setSwaggerVersion(VERSION);
        return swaggerResource;
    }

    @Override
    public void setEnvironment(@Nullable Environment environment) {
            this.environment = (ConfigurableEnvironment)environment;
    }
    private ConfigurableEnvironment getEnvironment() {
        return environment;
    }
}
